package net.warl0ck.mjjp;

import java.awt.*;
import java.io.BufferedInputStream;
import java.util.Vector;
import javax.swing.*;
import javax.swing.border.LineBorder;
import net.warl0ck.mjjp.MJTypes.*;

public class MJTable extends JPanel{
	private static final long serialVersionUID = 1L;
	private static final Color defclr = new Color(0,64,0);
	private Vector<MJPlace> places = new Vector<MJPlace>();
	private Vector<MJDiscardPlace> displaces = new Vector<MJDiscardPlace>();
	private MJCenterPlace centr;
	private MJConst cnst = new MJConst();
	private Dimension ico_sz;
	private Dimension ind_sz;
	private String img_dir;
	private float font_sz;
	public MJTable(MJFile file, MJParams params){
		init(params);
		drawTable(file);
	}
	public void drawTable(MJFile file) {
        GridBagConstraints cons = new GridBagConstraints();
		setLayout(new GridBagLayout());
		setBackground(defclr);
		setBorder(new LineBorder(new Color(0,100,0),1,true));
		removeAll();
		
		cons.insets = new Insets(0,0,0,0);

		Panel ang1 = new Panel();
		Panel ang2 = new Panel();
		Panel ang3 = new Panel();
		Panel ang4 = new Panel();
		centr = new MJCenterPlace(file);

		cons.gridx=0;	cons.gridy = 0;
		add(ang1,cons);
		cons.gridx=2;	cons.gridy = 0;
		add(ang2,cons);
		cons.gridx=0;	cons.gridy = 2;
		add(ang3,cons);
		cons.gridx=2;	cons.gridy = 2;
		add(ang4,cons);
		cons.gridx=1;	cons.gridy = 1;
		cons.fill = GridBagConstraints.BOTH;
		setIndicator("");
		add(centr,cons);
		
		for (MJName n: file.getNames()){
			MJPlace place = new MJPlace(file, n.getWind());
			int w = (getIcoSize().width*(file.getHandByWind(n.getWind()).getMaxtiles()+1))+1;
			int h = (getIcoSize().height+1)*3+1;
			if (n.getWind().equalsIgnoreCase("e")){
				cons.gridx=1;	cons.gridy = 2;
				place.setPreferredSize(new Dimension(w,h));
			}
			if (n.getWind().equalsIgnoreCase("s")){
				cons.gridx=2;	cons.gridy = 1;
				place.setPreferredSize(new Dimension(h,w));
			}
			if (n.getWind().equalsIgnoreCase("w")){
				cons.gridx=1;	cons.gridy = 0;
				place.setPreferredSize(new Dimension(w,h));
			}
			if (n.getWind().equalsIgnoreCase("n")){
				cons.gridx=0;	cons.gridy = 1;
				place.setPreferredSize(new Dimension(h,w));
			}
			add(place,cons);
			place.drawHand();
			place.drawOpen();
			place.drawFlower();
			places.add(place);
		}
	}
	private void init(MJParams params) {
		ImageIcon ico = new ImageIcon();
		ImageIcon ind = new ImageIcon();
		img_dir = params.getTypeTail();
		font_sz = params.getFont();
		if (getComponentCount()>0) removeAll();
		ico.setImage(loadImage("images/"+img_dir+"/oo.png").getImage());
		ind.setImage(loadImage("images/"+img_dir+"/ind.png").getImage());
		setIcoSize(new Dimension(ico.getIconWidth(),ico.getIconHeight()));
		setIndSize(new Dimension(ind.getIconWidth(),ind.getIconHeight()));
	}
	
	public void setIndicator(String wind){
		if (wind.equals("")){
			centr.getIndicator().setVisible(false);
		}else{
			centr.getIndicator().setVisible(true);
			centr.getIndicator().setWind(wind);
		}
	}
	
	public class MJPlace extends JPanel{
		private static final long serialVersionUID = 1L;
		private JPanel open = new JPanel();
		private JPanel hand = new JPanel();
		private JPanel title = new JPanel();
		private JPanel flower = new JPanel();
		private String _wind;
		private String _name;
		private MJFile _file;
        private GridBagConstraints cons = new GridBagConstraints();
		public MJPlace(MJFile file, String wind){
			setLayout(new GridBagLayout());
			setBackground(defclr);
			open.setBackground(defclr);
			hand.setBackground(defclr);
			title.setBackground(defclr);
			flower.setBackground(defclr);
			open.setLayout(new GridBagLayout());
			hand.setLayout(new GridBagLayout());
			title.setLayout(new GridBagLayout());
			flower.setLayout(new GridBagLayout());

			setFile(file);
			setWind(wind);
			setName(_file.getNameByWind(wind));
			setBorder(new LineBorder(new Color(0,100,0),1,true));
			
			cons.fill = GridBagConstraints.LINE_START;
			cons.insets = new Insets(1,1,1,1);
			cons.anchor = GridBagConstraints.CENTER;

			if (getWind().equalsIgnoreCase("e")){
				cons.gridx = 0;		cons.gridy = 0;
				cons.gridwidth = 2;	cons.gridheight = 1;
				add(open,cons);
				
				cons.gridx = 0;		cons.gridy = 1;
				cons.gridwidth = 2;	cons.gridheight = 1;
				add(hand,cons);
				
				cons.gridx = 0;		cons.gridy = 2;
				cons.gridwidth = 1;	cons.gridheight = 1;
				cons.anchor = GridBagConstraints.LINE_START;
				add(title,cons);
				
				cons.gridx = 1;		cons.gridy = 2;
				cons.gridwidth = 1;	cons.gridheight = 1;
				cons.anchor = GridBagConstraints.LINE_END;
				add(flower,cons);
			}
			if (getWind().equalsIgnoreCase("s")){
				cons.gridx = 0;		cons.gridy = 0;
				cons.gridwidth = 1;	cons.gridheight = 2;
				add(open,cons);
				
				cons.gridx = 1;		cons.gridy = 0;
				cons.gridwidth = 1;	cons.gridheight = 2;
				add(hand,cons);
				
				cons.gridx = 2;		cons.gridy = 1;
				cons.gridwidth = 1;	cons.gridheight = 1;
				cons.anchor = GridBagConstraints.PAGE_END;
				add(title,cons);
				
				cons.gridx = 2;		cons.gridy = 0;
				cons.gridwidth = 1;	cons.gridheight = 1;
				cons.anchor = GridBagConstraints.PAGE_START;
				add(flower,cons);
			}
			if (getWind().equalsIgnoreCase("w")){
				cons.gridx = 0;		cons.gridy = 2;
				cons.gridwidth = 2;	cons.gridheight = 1;
				add(open,cons);

				cons.gridx = 0;		cons.gridy = 1;
				cons.gridwidth = 2;	cons.gridheight = 1;
				add(hand,cons);
				
				cons.gridx = 1;		cons.gridy = 0;
				cons.gridwidth = 1;	cons.gridheight = 1;
				cons.anchor = GridBagConstraints.LINE_END;
				add(title,cons);
				
				cons.gridx = 0;		cons.gridy = 0;
				cons.gridwidth = 1;	cons.gridheight = 1;
				cons.anchor = GridBagConstraints.LINE_START;
				add(flower,cons);
			}
			if (getWind().equalsIgnoreCase("n")){
				cons.gridx = 2;		cons.gridy = 0;
				cons.gridwidth = 1;	cons.gridheight = 2;
				add(open,cons);
				
				cons.gridx = 1;		cons.gridy = 0;
				cons.gridwidth = 1;	cons.gridheight = 2;
				add(hand,cons);
				
				cons.gridx = 0;		cons.gridy = 0;
				cons.gridwidth = 1;	cons.gridheight = 1;
				cons.anchor = GridBagConstraints.PAGE_START;
				add(title,cons);
				
				cons.gridx = 0;		cons.gridy = 1;
				cons.gridwidth = 1;	cons.gridheight = 1;
				cons.anchor = GridBagConstraints.PAGE_END;
				add(flower,cons);
			}
			cons.anchor = GridBagConstraints.CENTER;
			JLabel lbl = new JLabel();
			lbl.setName("Name");
			Font fnt = lbl.getFont().deriveFont(font_sz).deriveFont(Font.PLAIN);
			
			lbl.setFont(fnt);
			JLabel tlk = new JLabel();
			tlk.setName("Talk");
			tlk.setFont(fnt.deriveFont(Font.ITALIC));
			if (getWind().equalsIgnoreCase("e")){
				cons.gridx = 0;		cons.gridy = 0;
				title.add(lbl,cons);
				cons.gridx = 1;		cons.gridy = 0;
				cons.insets = new Insets(0, 0, 0, 10);
				title.add(tlk,cons);
			}
			if (getWind().equalsIgnoreCase("w")){
				cons.gridx = 0;		cons.gridy = 0;
				title.add(lbl,cons);
				cons.gridx = 1;		cons.gridy = 0;
				cons.insets = new Insets(0, 0, 0, 10);
				title.add(tlk,cons);
			}
			if (getWind().equalsIgnoreCase("n")){
				cons.gridx = 0;		cons.gridy = 0;
				title.add(lbl,cons);
				cons.gridx = 0;		cons.gridy = 1;
				cons.insets = new Insets(10, 0, 0, 0);
				title.add(tlk,cons);
			}
			if (getWind().equalsIgnoreCase("s")){
				cons.gridx = 0;		cons.gridy = 1;
				title.add(lbl,cons);
				cons.gridx = 0;		cons.gridy = 0;
				cons.insets = new Insets(0, 0, 10, 0);
				title.add(tlk,cons);
			}
			drawName();
		}
		public void clearOpen(){
			getFile().getOpenByWind(_wind).clear();
			drawOpen();
		}
		public void clearHand(){
			getFile().getHandByWind(_wind).clear();
			drawHand();
		}
		public void clearFlower(){
			getFile().getFlowerByWind(_wind).clear();
			drawFlower();
		}
		public String getWind(){
			return _wind;
		}
		public void setWind(String w){
			_wind = w;
		}
		public void drawHand(){
			drawTails(hand,getFile().getHandByWind(_wind),true);
		}
		public void drawOpen(){
			drawTails(open,getFile().getOpenByWind(_wind),true);
		}
		public void drawFlower(){
			drawTails(flower,getFile().getFlowerByWind(_wind),false);
		}
		public void drawName(){
			for (Component c: title.getComponents()){
				if (c.getName().equals("Name")){
					((JLabel) c).setForeground(Color.WHITE);
					((JLabel) c).setHorizontalAlignment(JLabel.CENTER);
					if (getWind().toLowerCase().equals("n")) ((JLabel) c).setUI(new lrUI(true));
					if (getWind().toLowerCase().equals("s")) ((JLabel) c).setUI(new lrUI(false));
					String s = getName()+" ["+getWind().toUpperCase()+"]";
					((JLabel) c).setText(s);
				}
			}
		}
		public void drawTalk(String text){
			for (Component c: title.getComponents()){
				if (c.getName().equals("Talk")){
					((JLabel) c).setForeground(Color.YELLOW);
					((JLabel) c).setHorizontalAlignment(JLabel.CENTER);
					if (getWind().toLowerCase().equals("n")) ((JLabel) c).setUI(new lrUI(true));
					if (getWind().toLowerCase().equals("s")) ((JLabel) c).setUI(new lrUI(false));
					((JLabel) c).setText(text);
				}
			}
		}
		public void drawTails(JPanel where, MJHand h, boolean fill_empty){
			int i, max_fill;
	        GridBagConstraints cons2 = new GridBagConstraints();
	    	cons2.fill = GridBagConstraints.LINE_START;

			where.removeAll();
			if (h != null){
				if (fill_empty)
					max_fill = h.getMaxtiles();
				else
					max_fill = h.size();
			}else return;
			for (i = 0; i<max_fill; i++){
				JLabel tail = new JLabel();
				if (h.getTail(i) == null ){
					tail.setIcon(loadImage("images/"+img_dir+"/oo.png"));
				}else{
					tail.setIcon(loadImage("images/"+img_dir+"/"+h.getTail(i).toFile()));
				}
				if (getWind().equalsIgnoreCase("e")){
					cons2.gridx = i;
					cons2.gridy = 0;
					cons2.insets = new Insets(1,0,1,0);
					if (h.getTail(i) != null){
						if (h.getTail(i).is_rotate())
							tail.setUI(new lrUI(true));
					}
				}
				if (getWind().equalsIgnoreCase("w")){
					cons2.gridx = (h.getMaxtiles()-1)-i;
					cons2.gridy = 0;
					cons2.insets = new Insets(1,0,1,0);
					if (h.getTail(i) != null){
						tail.setUI(new xUI());
						if (h.getTail(i).is_rotate())
								tail.setUI(new lrUI(false));
					}
				}
				if (getWind().equalsIgnoreCase("n")){
					cons2.gridx = 0;
					cons2.gridy = i;
					cons2.insets = new Insets(0,1,0,1);
					if (h.getTail(i) == null || !h.getTail(i).is_rotate())
						tail.setUI(new lrUI(true));
				}
				if (getWind().equalsIgnoreCase("s")){
					cons2.gridx = 0;
					cons2.gridy = (h.getMaxtiles()-1)-i;
					cons.insets = new Insets(0,1,0,1);
					if (h.getTail(i) == null || !h.getTail(i).is_rotate())
						tail.setUI(new lrUI(false));
				}
				where.add(tail,cons2);
			}
			where.updateUI();
		}
		public void setName(String _name) {
			this._name = _name;
		}
		public String getName() {
			return _name;
		}
		public void setFile(MJFile _file) {
			this._file = _file;
		}
		public MJFile getFile() {
			return _file;
		}
	}
	private class MJCenterPlace extends JPanel{
		private static final long serialVersionUID = 1L;
        private GridBagConstraints cons = new GridBagConstraints();
        private MJIndicator indicator;
		public MJCenterPlace(MJFile file){
			setLayout(new GridBagLayout());
			setBackground(defclr);
			setPreferredSize(new Dimension(getIcoSize().width*(cnst.max_disc_cols+1)+(getIcoSize().height+1)*3+2,getIcoSize().width*(cnst.max_disc_cols+1)+(getIcoSize().height+1)*3+2));
			cons.insets = new Insets(0,0,0,0);
			cons.weightx = 1.0;
			cons.weighty = 1.0;
			for (MJHand h: file.getHands()){
				MJDiscardPlace displace = new MJDiscardPlace(file,h.getWind());
				int w1 = (getIcoSize().width*(cnst.max_disc_cols+1))+1;
				int h1 = (getIcoSize().height+1)*3+1;
				cons.fill = GridBagConstraints.BOTH;
				if (h.getWind().equalsIgnoreCase("n")){
					cons.gridx = 0;
					cons.gridy = 0;
					cons.gridheight = 2;
					cons.gridwidth = 1;
					cons.anchor = GridBagConstraints.FIRST_LINE_START;
					displace.setPreferredSize(new Dimension(h1,w1));
				}
				if (h.getWind().equalsIgnoreCase("w")){
					cons.gridx = 1;
					cons.gridy = 0;
					cons.gridheight = 1;
					cons.gridwidth = 2;
					cons.anchor = GridBagConstraints.FIRST_LINE_END;
					displace.setPreferredSize(new Dimension(w1,h1));
				}
				if (h.getWind().equalsIgnoreCase("e")){
					cons.gridx = 0;
					cons.gridy = 2;
					cons.gridheight = 1;
					cons.gridwidth = 2;
					cons.anchor = GridBagConstraints.LAST_LINE_START;
					displace.setPreferredSize(new Dimension(w1,h1));
				}
				if (h.getWind().equalsIgnoreCase("s")){
					cons.gridx = 2;
					cons.gridy = 1;
					cons.gridheight = 2;
					cons.gridwidth = 1;
					cons.anchor = GridBagConstraints.LAST_LINE_END;
					displace.setPreferredSize(new Dimension(h1,w1));
				}
				add(displace,cons);
				displaces.add(displace);
			}
			cons.gridx = 1;
			cons.gridy = 1;
			cons.gridheight = 1;
			cons.gridwidth = 1;
			cons.fill = GridBagConstraints.BOTH;
			indicator = new MJIndicator();
			add(indicator,cons);
			getIndicator().setWind("");
		}
		public void setIndicator(MJIndicator indicator) {
			this.indicator = indicator;
		}
		public MJIndicator getIndicator() {
			return indicator;
		}
	}
	
	public class MJDiscardPlace extends JPanel{
		private static final long serialVersionUID = 1L;
        private GridBagConstraints cons = new GridBagConstraints();
        private String wind;
        private MJDiscard mydisc;
		public MJDiscardPlace(MJFile file, String wind){
			setLayout(new GridBagLayout());
			setBackground(defclr);
			setWind(wind);
			mydisc = file.getDiscardByWind(getWind());
			if (mydisc!=null && mydisc.size()>0)
				drawDiscard();
		}
		public void setWind(String wind) {
			this.wind = wind;
		}
		public String getWind() {
			return wind;
		}
		public void drawDiscard(){
			int cnt = mydisc.size();
			int maxcol = cnst.max_disc_cols;
			int maxrow = (int) Math.floor(cnt/maxcol);
			cons.fill = GridBagConstraints.BOTH;
			cons.insets = new Insets(1,1,1,1);
			cons.anchor = GridBagConstraints.FIRST_LINE_START;
			removeAll();
			for (int i = 0; i<cnt; i++){
				JLabel tail = new JLabel();
				int row = (int) Math.ceil(i/maxcol);
				int col = i-row*maxcol;
				
				tail.setIcon(loadImage("images/"+img_dir+"/"+mydisc.getTail(i).toFile()));
				if (getWind().equalsIgnoreCase("e")){
					cons.gridx = col;
					cons.gridy = row;
					cons.insets = new Insets(1,0,1,0);
					if (mydisc.getTail(i).is_rotate())
						tail.setUI(new lrUI(true));
				}
				if (getWind().equalsIgnoreCase("w")){
					cons.gridx = maxcol-1-col;
					cons.gridy = maxrow-row;
					cons.insets = new Insets(1,0,1,0);
					tail.setUI(new xUI());
					if (mydisc.getTail(i).is_rotate())
						tail.setUI(new lrUI(false));
				}
				if (getWind().equalsIgnoreCase("n")){
					cons.gridx = maxrow-row;
					cons.gridy = col;
					cons.insets = new Insets(0,1,0,1);
					tail.setUI(new lrUI(true));
					if (mydisc.getTail(i).is_rotate())
						tail.setUI(new xUI());
				}
				if (getWind().equalsIgnoreCase("s")){
					cons.gridx = row;
					cons.gridy = maxcol-1-col;
					cons.insets = new Insets(0,1,0,1);
					if (!mydisc.getTail(i).is_rotate())
						tail.setUI(new lrUI(false));
				}
				add(tail,cons);
			}
			updateUI();
		}
	}
	
	public Vector<MJPlace> getPlaces(){
		return places;
	}

	public MJPlace getPlaceByWind(String wind){
		for (MJPlace p:places){
			if (p.getWind().equalsIgnoreCase(wind)) return p;
		}
		return null;
	}

	public MJDiscardPlace getDiscardPlaceByWind(String wind){
		for (MJDiscardPlace d:displaces){
			if (d.getWind().equalsIgnoreCase(wind)) return d;
		}
		return null;
	}

	public Vector<MJDiscardPlace> getDiscardPlaces(){
		return displaces;
	}
	
	public class MJIndicator extends JPanel{
		private static final long serialVersionUID = 1L;
		private JLabel ind;
		private String img = "images/"+img_dir+"/ind.png";
		public MJIndicator(){
			setBackground(defclr);
			setLayout(new BorderLayout());
			setWind("e");
			setPreferredSize(getIndSize());
		}
		public void setWind(String wind){
			removeAll();
			if (! wind.isEmpty()){
				ind = new JLabel(loadImage(img));
				if (wind.equalsIgnoreCase("w")) ind.setUI(new xUI());
				if (wind.equalsIgnoreCase("s")) ind.setUI(new lrUI(false));
				if (wind.equalsIgnoreCase("n")) ind.setUI(new lrUI(true));
				add(ind,BorderLayout.CENTER);
			}
		}
	}

	public ImageIcon loadImage(String path) {
	    int MAX_IMAGE_SIZE = 102400;
	    int count = 0;
	    BufferedInputStream imgStream = new BufferedInputStream(getClass().getResourceAsStream(path));
	    if (imgStream != null) {
	        byte buf[] = new byte[MAX_IMAGE_SIZE];
	        try {
	            count = imgStream.read(buf);
	            imgStream.close();
	        } catch (java.io.IOException ioe) {
	    		JOptionPane.showMessageDialog(this.getParent(),"Couldn't read stream from file: " + path,"Ошибка",JOptionPane.ERROR_MESSAGE);
	            return null;
	        }
	        if (count <= 0) {
	    		JOptionPane.showMessageDialog(this.getParent(),"Empty file: " + path,"Ошибка",JOptionPane.ERROR_MESSAGE);
	            return null;
	        }
	        return new ImageIcon(Toolkit.getDefaultToolkit().createImage(buf));
	    } else {
    		JOptionPane.showMessageDialog(this.getParent(),"Couldn't find file: " + path,"Ошибка",JOptionPane.ERROR_MESSAGE);
	        return null;
	    }
	}
	public void setIcoSize(Dimension ico_sz) {
		this.ico_sz = ico_sz;
	}
	public Dimension getIcoSize() {
		return ico_sz;
	}
	public void setIndSize(Dimension ind_sz) {
		this.ind_sz = ind_sz;
	}
	public Dimension getIndSize() {
		return ind_sz;
	}
}
